﻿using System;
using WeDonekRpc.CacheClient.Interface;
using WeDonekRpc.Helper;
using StackExchange.Redis;
namespace WeDonekRpc.CacheClient.Redis
{
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    internal class SubscriberController<T> : DataSyncClass, ISubscriberController
    {
        private RedisClient _Client;
        public SubscriberController (string name, Action<T> notice)
        {
            this._NoticeCallBack = notice;
            this.SubName = name;
        }

        public string SubName
        {
            get;
        }
        private readonly Action<T> _NoticeCallBack = null;

        private ISubscriber _Subscriber = null;
        protected override void SyncData ()
        {
            this._Client = RedisHelper.GetNewClient(this.SubName);
            this._Client.RetryLoad += this._Client_RetryLoad;
            if (!this._Subscriber.IsConnected())
            {
                throw new ErrorException("redis.con.error");
            }
            this._InitSubscribe();
        }

        private void _Client_RetryLoad ()
        {
            this._InitSubscribe();
        }

        private void _InitSubscribe ()
        {
            this._Subscriber = this._Client.GetSubscriber();
            this._Subscriber.Subscribe(this.SubName, (a, msg) =>
            {
                if (msg.IsNull || msg.IsNullOrEmpty)
                {
                    return;
                }
                else if (RedisTools.GetT<T>(msg, out T data))
                {
                    this._NoticeCallBack.Invoke(data);
                }
            });
        }

        public override void Dispose ()
        {
            base.Dispose();
            if (this._Subscriber != null && this._Subscriber.IsConnected())
            {
                this._Subscriber.Unsubscribe(this.SubName);
                this._Client.Dispose();
            }
        }
    }
}
